import { App } from 'vue'
import { useErrorLogStore } from '@/store/errorLog'
import { isString, isArray } from '@/utils/validate'
import settings from '@/settings'

// you can set in settings.ts
// errorLog:'production' | ['production', 'development']
const { errorLog: needErrorLog } = settings

function checkNeed() {
  const env = process.env.NODE_ENV
  if (isString(needErrorLog)) {
    return env === needErrorLog
  }
  if (isArray(needErrorLog)) {
    return needErrorLog.includes(env)
  }
  return false
}

export function setupErrorLog(app: App) {
  if (checkNeed()) {
    app.config.errorHandler = function(err, instance, info) {
      // Don't ask me why I use Vue.nextTick, it just a hack.
      // detail see https://forum.vuejs.org/t/dispatch-in-vue-config-errorhandler-has-some-problem/23500
      Promise.resolve().then(() => {
        const errorLogStore = useErrorLogStore()
        errorLogStore.addErrorLog({
          err,
          instance,
          info,
          url: window.location.href
        })
      })
    }
  }
}

export interface IErrorLog {
  err: Error
  vm: any
  info: string
  url: string
}

export interface IErrorLogState {
  logs: IErrorLog[]
}

const state: IErrorLogState = {
  logs: []
}

const mutations = {
  ADD_ERROR_LOG: (state: IErrorLogState, log: IErrorLog) => {
    state.logs.push(log)
  },
  CLEAR_ERROR_LOG: (state: IErrorLogState) => {
    state.logs.splice(0)
  }
}

const actions = {
  addErrorLog({ commit }: any, log: IErrorLog) {
    commit('ADD_ERROR_LOG', log)
  },
  clearErrorLog({ commit }: any) {
    commit('CLEAR_ERROR_LOG')
  }
}

export default {
  namespaced: true,
  state,
  mutations,
  actions
}
